home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / MHITM.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  20KB  |  738 lines

  1. /*    SCCS Id: @(#)mhitm.c    3.0    89/11/27
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include    "hack.h"
  6. #ifdef NAMED_ITEMS
  7. #  include "artifact.h"
  8. #endif
  9.  
  10. #ifdef OVLB
  11.  
  12. static boolean NEARDATA vis, NEARDATA far_noise;
  13. static long NEARDATA noisetime;
  14. static struct obj NEARDATA *otmp;
  15.  
  16. static void FDECL(mrustm, (struct monst *, struct monst *, struct obj *));
  17. static int FDECL(hitmm, (struct monst *,struct monst *,struct attack *));
  18. static int FDECL(gazemm, (struct monst *,struct monst *,struct attack *));
  19. static int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *));
  20. static int FDECL(explmm, (struct monst *,struct monst *,struct attack *));
  21. static int FDECL(mdamagem, (struct monst *,struct monst *,struct attack *));
  22. static void FDECL(mswingsm, (struct monst *, struct monst *, struct obj *));
  23. static void FDECL(noises,(struct monst *,struct attack *));
  24. static void FDECL(missmm,(struct monst *,struct monst *,struct attack *));
  25.  
  26. static void
  27. noises(magr, mattk)
  28.     register struct monst *magr;
  29.     register struct    attack *mattk;
  30. {
  31.     boolean farq = (dist(magr->mx, magr->my) > 15);
  32.  
  33.     if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) {
  34.         far_noise = farq;
  35.         noisetime = moves;
  36.         You("hear %s%s.",
  37.             (mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",
  38.             farq ? " in the distance" : "");
  39.     }
  40. }
  41.  
  42. static
  43. void
  44. missmm(magr, mdef, mattk)
  45.     register struct monst *magr, *mdef;
  46.     struct attack *mattk;
  47. {
  48.     char buf[BUFSZ];
  49.  
  50.     if(vis) {
  51.         if(mdef->mimic) seemimic(mdef);
  52.         if(magr->mimic) seemimic(magr);
  53.         if (could_seduce(magr,mdef,mattk) && !magr->mcan)
  54.             Sprintf(buf, "%s pretends to be friendly to",
  55.                                 Monnam(magr));
  56.         else
  57.             Sprintf(buf,"%s misses", Monnam(magr));
  58.         pline("%s %s.", buf, mon_nam(mdef));
  59.     } else  noises(magr, mattk);
  60. }
  61.  
  62. /*
  63.  * fightm returns 3 if no attack, otherwise the results of mattackm
  64.  */
  65. int
  66. fightm(mtmp)        /* have monsters fight each other */
  67.     register struct monst *mtmp;
  68. {
  69. register struct monst *mon, *nmon;
  70. #ifdef LINT
  71.     nmon = 0;
  72. #endif
  73.     for(mon = fmon; mon; mon = nmon) {
  74.         nmon = mon->nmon;
  75.         if(nmon == mtmp) nmon = mtmp->nmon;
  76.         if(mon != mtmp) {
  77.         if(dist2(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3)
  78.         /* note: grid bug check needed here as well as in mattackm */
  79.             if(mtmp->data != &mons[PM_GRID_BUG] || mtmp->mx==mon->mx
  80.                 || mtmp->my==mon->my)
  81.             return(mattackm(mtmp,mon));
  82.         }
  83.     }
  84.     return(3);
  85. }
  86.  
  87. /*
  88.  * mattackm returns -1 (magr died), 0 (miss), 1 (mdef hit), or 2 (mdef killed)
  89.  *
  90.  * Each successive attack has a lower probability of hitting.  Some
  91.  * rely on the success of previous attacks.
  92.  *
  93.  * In the case of exploding monsters, the monster dies as well.
  94.  */
  95. int
  96. mattackm(magr, mdef)
  97.     register struct monst *magr,*mdef;
  98. {
  99.     int    i, tmp, nsum, sum[NATTK];
  100.     struct    attack    *mattk;
  101.     struct    permonst *pa, *pd;
  102.     schar    strike;
  103.  
  104.     if(!magr || !mdef) return(0);        /* mike@genat */
  105.     pa = magr->data; pd = mdef->data;
  106.     if(!magr->mcanmove) return(0);        /* riv05!a3 */
  107.     if(pa==&mons[PM_GRID_BUG] && magr->mx != mdef->mx
  108.                         && magr->my != mdef->my)
  109.         return(0);
  110.  
  111. /*    Calculate the armour class differential.    */
  112.  
  113.     tmp = pd->ac + magr->m_lev;
  114.     if(mdef->mconf || !mdef->mcanmove || mdef->msleep){
  115.         tmp += 4;
  116.         if(mdef->msleep) mdef->msleep = 0;
  117.     }
  118.  
  119.     if (is_elf(magr->data) && is_orc(mdef->data)) tmp++;
  120.  
  121. /*    Set up visibility of action            */
  122.     vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my));
  123.  
  124. /*    Set flag indicating monster has moved this turn.  Necessary since a
  125.  *    monster might get an attack out of sequence (i.e. before its move) in
  126.  *    some cases, in which case this still counts as its move for the round
  127.  *    and it shouldn't move again.
  128.  */
  129.     magr->mlstmv = moves;
  130.  
  131. /*    Now perform all attacks for the monster.    */
  132.  
  133.     for(i=0; i<NATTK; i++) sum[i] = 0;
  134.     for(i = nsum = 0; i < NATTK; nsum |= sum[i++]) {
  135.         mattk = &(pa->mattk[i]);
  136.         otmp = (struct obj *)0;
  137.         switch(mattk->aatyp) {
  138.  
  139.         case AT_WEAP:        /* "hand to hand" attacks */
  140.             otmp = select_hwep(magr);
  141.             if(otmp) {
  142.                 if (vis) mswingsm(magr, mdef, otmp);
  143.                 tmp += hitval(otmp, pd);
  144.             }
  145.         case AT_CLAW:
  146.         case AT_KICK:
  147.         case AT_BITE:
  148.         case AT_STNG:
  149.         case AT_TUCH:
  150.         case AT_BUTT:
  151.             if((strike = (tmp > rnd(20+i)))) {
  152.                 sum[i] = hitmm(magr, mdef, mattk);
  153.                 if(sum[i] == -1) return(-1);
  154.             } else    missmm(magr, mdef, mattk);
  155.             break;
  156.  
  157.         case AT_HUGS:    /* automatic if prev two attacks succeed */
  158.             strike = 1;
  159.             if(sum[i-1] && sum[i-2]) {
  160.                 sum[i] = hitmm(magr, mdef, mattk);
  161.                 if(sum[i] == -1) return(-1);
  162.             }
  163.             break;
  164.  
  165.         case AT_GAZE:    /* will not wake up a sleeper */
  166.             strike = 0;
  167.             sum[i] = gazemm(magr, mdef, mattk);
  168.             break;
  169.  
  170.         case AT_EXPL:    /* automatic hit if next to */
  171.             strike = -1;
  172.             sum[i] = explmm(magr, mdef, mattk);
  173.             break;
  174.  
  175.         case AT_ENGL:
  176.             if((strike = (tmp > rnd(20+i))))
  177.                 sum[i]= gulpmm(magr, mdef, mattk);
  178.             else    missmm(magr, mdef, mattk);
  179.             break;
  180.  
  181.         default:        /* no attack */
  182.             strike = 0;
  183.             break;
  184.         }
  185.         if(sum[i] == 2) return(2);      /* defender dead */
  186.         if(strike)        mdef->msleep = 0;
  187.         if(strike == -1)   return(-1);        /* attacker dead */
  188.         nsum |= sum[i];
  189.     }
  190.     return(nsum);
  191. }
  192.  
  193. /* hitmm returns 0 (miss), 1 (hit), 2 (kill), or -1 (magr died) */
  194. static int
  195. hitmm(magr, mdef, mattk)
  196.     register struct monst *magr,*mdef;
  197.     struct    attack *mattk;
  198. {
  199.     if(vis){
  200.         int compat;
  201.         char buf[BUFSZ];
  202.  
  203.         if(mdef->mimic) seemimic(mdef);
  204.         if(magr->mimic) seemimic(magr);
  205.         if((compat = could_seduce(magr,mdef,mattk)) && !magr->mcan) {
  206.             Sprintf(buf, "%s %s", Monnam(magr),
  207.                 mdef->mcansee ? "smiles at" : "talks to");
  208.             pline("%s %s %s.", buf, mon_nam(mdef),
  209.                 compat == 2 ?
  210.                     "engagingly" : "seductively");
  211.         } else {
  212.             switch (mattk->aatyp) {
  213.             case AT_BITE:
  214.                 Sprintf(buf,"%s bites", Monnam(magr));
  215.                 break;
  216.             case AT_STNG:
  217.                 Sprintf(buf,"%s stings", Monnam(magr));
  218.                 break;
  219.             case AT_BUTT:
  220.                 Sprintf(buf,"%s butts", Monnam(magr));
  221.                 break;
  222.             case AT_TUCH:
  223.                 Sprintf(buf,"%s touches", Monnam(magr));
  224.                 break;
  225.             case AT_HUGS:
  226.                 if (magr != u.ustuck) {
  227.                     Sprintf(buf,"%s squeezes", Monnam(magr));
  228.                     break;
  229.                 }
  230.             default:
  231.                 Sprintf(buf,"%s hits", Monnam(magr));
  232.             }
  233.         }
  234.         pline("%s %s.", buf, mon_nam(mdef));
  235.     } else  noises(magr, mattk);
  236.     return(mdamagem(magr, mdef, mattk));
  237. }
  238.  
  239. static int
  240. gazemm(magr, mdef, mattk)
  241.     register struct monst *magr, *mdef;
  242.     struct attack *mattk;
  243. {
  244.     char buf[BUFSZ];
  245.  
  246.     if(vis) {
  247.         Sprintf(buf,"%s gazes at", Monnam(magr));
  248.         pline("%s %s.", buf, mon_nam(mdef));
  249.     }
  250.  
  251.     if (!mdef->mcansee || mdef->msleep) {
  252.  
  253.         if(vis) pline("but nothing happens.");
  254.         return(0);
  255.     }
  256.  
  257.     return(mdamagem(magr, mdef, mattk));
  258. }
  259.  
  260. static int
  261. gulpmm(magr, mdef, mattk)
  262.     register struct monst *magr, *mdef;
  263.     register struct    attack *mattk;
  264. {
  265.     int    mx, my, tmp;
  266.     char buf[BUFSZ];
  267.  
  268.     if(mdef->data->msize >= MZ_HUGE) return 0;
  269.  
  270.     if(vis) {
  271.         Sprintf(buf,"%s swallows", Monnam(magr));
  272.         pline("%s %s.", buf, mon_nam(mdef));
  273.     }
  274.  
  275.     mx = magr->mx;
  276.     my = magr->my;
  277.      /* move over top of the defender */
  278.     if(cansee(mdef->mx, mdef->my))    unpmon(mdef);
  279.     if(cansee(magr->mx, magr->my))    unpmon(magr);
  280.     magr->mx = mdef->mx;
  281.     magr->my = mdef->my;
  282.     if(cansee(magr->mx, magr->my))    pmon(magr);
  283.     if((tmp = mdamagem(magr, mdef, mattk)) == 2) {
  284.         remove_monster(mx, my);
  285.         place_monster(magr, magr->mx, magr->my);
  286.         /* if mdamagem left a corpse it erased magr's symbol */
  287.         unpmon(magr);
  288.         pmon(magr);
  289.         return(2);    /* defender died */
  290.     } else {        /* defender survived */
  291.         if(cansee(mdef->mx, mdef->my))
  292.             pline("%s is regurgitated!", Monnam(mdef));
  293.         if(cansee(magr->mx, magr->my))    unpmon(magr);
  294.         magr->mx = mx;
  295.         magr->my = my;
  296.         /* move off of defender */
  297.         if(cansee(magr->mx, magr->my))    pmon(magr);
  298.         if(cansee(mdef->mx, mdef->my))    pmon(mdef);
  299.         nscr();
  300.         return(tmp);
  301.     }
  302. }
  303.  
  304. static int
  305. explmm(magr, mdef, mattk)
  306.     register struct monst *magr, *mdef;
  307.     register struct    attack *mattk;
  308. {
  309.  
  310.     if(cansee(magr->mx, magr->my))
  311.         pline("%s explodes!", Monnam(magr));
  312.     else    noises(magr, mattk);
  313.  
  314.     (void) mdamagem(magr, mdef, mattk);
  315.  
  316.     if(magr->mtame)
  317.         You("have a sad feeling for a moment, then it passes.");
  318.     mondead(magr);
  319.     return(2);
  320. }
  321.  
  322. static const char psf[] =
  323.     "have a peculiarly sad feeling for a moment, then it passes.";
  324.  
  325. static int
  326. mdamagem(magr, mdef, mattk)
  327.     register struct monst    *magr, *mdef;
  328.     register struct attack    *mattk;
  329. {
  330.     struct    permonst *ptr, *pd = mdef->data;
  331.     int    tmp = d((int)mattk->damn,(int)mattk->damd);
  332.     char buf[BUFSZ];
  333.  
  334.     if(mdef->data == &mons[PM_COCKATRICE] && !resists_ston(magr->data) &&
  335.        (mattk->aatyp != AT_WEAP || !otmp) &&
  336.        (mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL) &&
  337.        (!is_mercenary(magr->data) || !m_carrying(magr, LEATHER_GLOVES))) {
  338.        /* Note: other monsters may carry gloves, only soldiers have them */
  339.        /* as their "armor" and can be said to wear them */
  340.         if (vis) pline("%s turns to stone!", Monnam(magr));
  341.         else if (magr->mtame) You(psf);
  342.         monstone(magr);
  343.         return -1;
  344.     }
  345.  
  346.     switch(mattk->adtyp) {
  347.         case AD_DGST:
  348.         if(flags.verbose && flags.soundok) verbalize("Burrrrp!");
  349.         tmp = mdef->mhp;
  350.         break;
  351.         case AD_STUN:
  352.         if (magr->mcan) break;
  353.         if(vis) pline("%s staggers for a moment.", Monnam(mdef));
  354.         mdef->mstun = 1;
  355.         /* fall through */
  356.         case AD_WERE:
  357.         case AD_HEAL:
  358.         case AD_LEGS:
  359.         case AD_PHYS:
  360.         if (mattk->aatyp == AT_KICK && thick_skinned(mdef->data))
  361.             tmp = 0;
  362.         else if(mattk->aatyp == AT_WEAP) {
  363.             if(otmp) {
  364.             tmp += dmgval(otmp, pd);
  365. #ifdef NAMED_ITEMS
  366.             if(spec_ability(otmp, SPFX_DRLI) &&
  367.                 !resists_drli(mdef->data)) {
  368.                 int dam = rnd(8);
  369.  
  370.                 tmp += dam;
  371.                 if(vis)
  372.                 pline("The %s blade drains the life from %s!",
  373.                     Hallucination ? hcolor() : black,
  374.                     mon_nam(mdef));
  375.                 mdef->mhpmax -= dam;
  376.                 if (mdef->m_lev == 0)
  377.                 tmp = mdef->mhp;
  378.                 else mdef->m_lev--;
  379.             }
  380. #endif
  381.             mrustm(magr, mdef, otmp);
  382.             }
  383.         }
  384.         break;
  385.         case AD_FIRE:
  386.         if (magr->mcan) {
  387.             tmp = 0;
  388.             break;
  389.         }
  390.         if(vis) pline("%s is on fire!", Monnam(mdef));
  391.         tmp += destroy_mitem(mdef, SCROLL_SYM, AD_FIRE);
  392. #ifdef SPELLS
  393.         tmp += destroy_mitem(mdef, SPBOOK_SYM, AD_FIRE);
  394. #endif
  395.         if(resists_fire(pd)) {
  396.             pline("The fire doesn't seem to burn %s!", mon_nam(mdef));
  397.             shieldeff(mdef->mx, mdef->my);
  398. #ifdef GOLEMS
  399.             golemeffects(mdef, AD_FIRE, tmp);
  400. #endif /* GOLEMS */
  401.             tmp = 0;
  402.         }
  403.         /* only potions damage resistant players in destroy_item */
  404.         tmp += destroy_mitem(mdef, POTION_SYM, AD_FIRE);
  405.         break;
  406.         case AD_COLD:
  407.         if (magr->mcan) {
  408.             tmp = 0;
  409.             break;
  410.         }
  411.         if(vis) pline("%s is covered in frost!", Monnam(mdef));
  412.         if(resists_cold(pd)) {
  413.             pline("The frost doesn't seem to chill %s!",
  414.             mon_nam(mdef));
  415.             shieldeff(mdef->mx, mdef->my);
  416. #ifdef GOLEMS
  417.             golemeffects(mdef, AD_COLD, tmp);
  418. #endif /* GOLEMS */
  419.             tmp = 0;
  420.         }
  421.         tmp += destroy_mitem(mdef, POTION_SYM, AD_COLD);
  422.         break;
  423.         case AD_ELEC:
  424.         if (magr->mcan) {
  425.             tmp = 0;
  426.             break;
  427.         }
  428.         if(vis) pline("%s gets zapped!", Monnam(mdef));
  429.         tmp += destroy_mitem(mdef, WAND_SYM, AD_ELEC);
  430.         if(resists_elec(pd)) {
  431.             pline("The zap doesn't shock %s!", mon_nam(mdef));
  432.             shieldeff(mdef->mx, mdef->my);
  433. #ifdef GOLEMS
  434.             golemeffects(mdef, AD_ELEC, tmp);
  435. #endif /* GOLEMS */
  436.             tmp = 0;
  437.         }
  438.         /* only rings damage resistant players in destroy_item */
  439.         tmp += destroy_mitem(mdef, RING_SYM, AD_ELEC);
  440.         break;
  441.         case AD_ACID:
  442.         if (magr->mcan) {
  443.             tmp = 0;
  444.             break;
  445.         }
  446.         if(resists_acid(pd)) {
  447.             pline("%s is covered in acid, but it seems harmless.",
  448.             Monnam(mdef));
  449.             tmp = 0;
  450.         } else {
  451.             pline("%s is covered in acid!", Monnam(mdef));
  452.             pline("It burns %s!", mon_nam(mdef));
  453.         }
  454.         break;
  455.         case AD_RUST:
  456. #ifdef GOLEMS
  457.         if (!magr->mcan && pd == &mons[PM_IRON_GOLEM]) {
  458.             if (vis) pline("%s falls to pieces!", Monnam(mdef));
  459.             else if(mdef->mtame)
  460.                  pline("May %s rust in peace.", mon_nam(mdef));
  461.             mondied(mdef);
  462.             magr->mhpmax = magr->mhpmax +
  463.                                             (1 + rn2((int)mdef->m_lev+1));
  464.             ptr = grow_up(magr);
  465.             if(!ptr) return(-1);
  466.             return(2);
  467.         }
  468. #endif /* GOLEMS */
  469.         tmp = 0;
  470.         break;
  471.         case AD_DCAY:
  472. #ifdef GOLEMS
  473.         if (!magr->mcan && (pd == &mons[PM_WOOD_GOLEM] ||
  474.             pd == &mons[PM_LEATHER_GOLEM])) {
  475.             if (vis) pline("%s falls to pieces!", Monnam(mdef));
  476.             else if(mdef->mtame)
  477.                  pline("May %s rot in peace.", mon_nam(mdef));
  478.             mondied(mdef);
  479.             magr->mhpmax = magr->mhpmax +
  480.                                    (1 + rn2((int)mdef->m_lev+1));
  481.             ptr = grow_up(magr);
  482.             if(!ptr) return(-1);
  483.             return(2);
  484.         }
  485. #endif /* GOLEMS */
  486.         tmp = 0;
  487.         break;
  488.         case AD_STON:
  489.         if(!resists_ston(pd)) {
  490.             magr->mhpmax = magr->mhpmax +
  491.                                               (1 + rn2((int)mdef->m_lev+1));
  492.             if(vis) pline("%s turns to stone!", Monnam(mdef));
  493.             else if(mdef->mtame) You(psf);
  494.             monstone(mdef);
  495.             ptr = grow_up(magr);
  496.             if(!ptr) return(-1);
  497.             return(2);
  498.         }
  499.         tmp = 0;    /* no damage if this fails */
  500.         break;
  501.         case AD_TLPT:
  502.         if(!magr->mcan && tmp < mdef->mhp) {
  503.             rloc(mdef);
  504.             if(vis && !cansee(mdef->mx, mdef->my))
  505.             pline("%s suddenly disappears!", Monnam(mdef));
  506.         }
  507.         break;
  508.         case AD_SLEE:
  509.         if(!resists_sleep(pd) && !magr->mcan && !mdef->msleep
  510.                             && mdef->mcanmove) {
  511.             if (vis) {
  512.             Strcpy(buf, Monnam(mdef));
  513.             pline("%s is put to sleep by %s.", buf, mon_nam(magr));
  514.             }
  515.             mdef->mcanmove = 0;
  516.             mdef->mfrozen = rnd(10);
  517.         }
  518.         break;
  519.         case AD_PLYS:
  520.         if(!magr->mcan && mdef->mcanmove) {
  521.             if (vis) {
  522.             Strcpy(buf, Monnam(mdef));
  523.             pline("%s is frozen by %s.", buf, mon_nam(magr));
  524.             }
  525.             mdef->mcanmove = 0;
  526.             mdef->mfrozen = rnd(10);
  527.         }
  528.         break;
  529.         case AD_SLOW:
  530.         if(!magr->mcan && vis && mdef->mspeed != MSLOW) {
  531.             if (vis) pline("%s slows down.", Monnam(mdef));
  532.             if (mdef->mspeed == MFAST) mdef->mspeed = 0;
  533.             else mdef->mspeed = MSLOW;
  534.         }
  535.         break;
  536.         case AD_CONF:
  537.         /* Since confusing another monster doesn't have a real time
  538.          * limit, setting spec_used would not really be right (though
  539.          * we still should check for it).
  540.          */
  541.         if(!magr->mcan && vis && !mdef->mconf && !magr->mspec_used) {
  542.             pline("%s looks confused.", Monnam(mdef));
  543.             mdef->mconf = 1;
  544.         }
  545.         break;
  546.         case AD_BLND:
  547.         if(!magr->mcan && haseyes(pd)) {
  548.  
  549.             if(vis && mdef->mcansee)
  550.             pline("%s is blinded.", Monnam(mdef));
  551.             {
  552.             register unsigned rnd_tmp;
  553.             rnd_tmp = d((int)mattk->damn, (int)mattk->damd);
  554.             mdef->mcansee = 0;
  555.             if((mdef->mblinded + rnd_tmp) > 127)
  556.                 mdef->mblinded = 127;
  557.             else mdef->mblinded += rnd_tmp;
  558.             }
  559.         }
  560.         tmp = 0;
  561.         break;
  562.         case AD_CURS:
  563.         if(!night() && (magr->data == &mons[PM_GREMLIN])) break;
  564.         if(!magr->mcan && !rn2(10)) {
  565.             if (is_were(mdef->data) && mdef->data->mlet != S_HUMAN)
  566.             were_change(mdef);
  567. #ifdef GOLEMS
  568.             if (mdef->data == &mons[PM_CLAY_GOLEM]) {
  569.                 if (vis) {
  570.                 pline("Some writing vanishes from %s's head!",
  571.                     mon_nam(mdef));
  572.                 pline("%s dies!", Monnam(mdef));
  573.                 }
  574.                 else if (mdef->mtame)
  575.     You("have a strangely sad feeling for a moment, then it passes.");
  576.                 mondied(mdef);
  577.                 magr->mhpmax = magr->mhpmax +
  578.                               (1 + rn2((int)mdef->m_lev+1));
  579.                 ptr = grow_up(magr);
  580.                 if(!ptr) return(-1);
  581.                 return(2);
  582.               }
  583. #endif /* GOLEMS */
  584.             mdef->mcan = 1;
  585.             if (flags.soundok) {
  586.                 if (!vis) You("hear laughter.");
  587.                 else pline("%s chuckles.", Monnam(magr));
  588.             }
  589.         }
  590.         break;
  591.         case AD_SGLD:
  592.         tmp = 0;
  593.         if (magr->mcan || !mdef->mgold) break;
  594.         /* technically incorrect; no check for stealing gold from
  595.          * between mdef's feet...
  596.          */
  597.         magr->mgold += mdef->mgold;
  598.         mdef->mgold = 0;
  599.         if (vis) {
  600.             Strcpy(buf, Monnam(magr));
  601.             pline("%s steals some gold from %s.", buf,
  602.                                 mon_nam(mdef));
  603.         }
  604.         break;
  605.         case AD_DRLI:
  606.         if(rn2(2) && !resists_drli(mdef->data)) {
  607.             tmp = d(2,6);
  608.             if (vis)
  609.                 kludge("%s suddenly seems weaker!", Monnam(mdef));
  610.             mdef->mhpmax -= tmp;
  611.             if (mdef->m_lev == 0)
  612.                 tmp = mdef->mhp;
  613.             else mdef->m_lev--;
  614.             /* Automatic kill if drained past level 0 */
  615.         }
  616.         break;
  617. #ifdef SEDUCE
  618.         case AD_SSEX:
  619. #endif
  620.         case AD_SITM:    /* for now these are the same */
  621.         case AD_SEDU:
  622.         if (!magr->mcan && mdef->minvent) {
  623.                otmp = mdef->minvent;
  624.             mdef->minvent = otmp->nobj;
  625.             otmp->nobj = magr->minvent;
  626.             magr->minvent = otmp;
  627.             if (vis) {
  628.                 Strcpy(buf, Monnam(magr));
  629.                 pline("%s steals %s from %s!", buf,
  630.                         doname(otmp), mon_nam(mdef));
  631.             }
  632.         }
  633.         tmp = 0;
  634.         break;
  635.         case AD_DRST:
  636.         case AD_DRDX:
  637.         case AD_DRCO:
  638.         if (!magr->mcan && !rn2(8)) {
  639.             if (vis)
  640.             pline("%s's %s was poisoned!", Monnam(magr),
  641.                 mattk->aatyp==AT_BITE ? "bite" : "sting");
  642.             if (resists_poison(mdef->data)) {
  643.             if (vis)
  644.                 pline("The poison doesn't seem to affect %s.",
  645.                 mon_nam(mdef));
  646.             } else {
  647.             if (rn2(10)) tmp += rn1(10,6);
  648.             else {
  649.                 if (vis) pline("The poison was deadly...");
  650.                 tmp = mdef->mhp;
  651.             }
  652.             }
  653.         }
  654.         break;
  655.         case AD_STCK:
  656.         case AD_WRAP: /* monsters cannot grab one another, it's too hard */
  657.         break;
  658.         default:    tmp = 0;
  659.             break;
  660.     }
  661.     if(!tmp) return(1);
  662.  
  663.     if((mdef->mhp -= tmp) < 1) {
  664.         magr->mhpmax = magr->mhpmax + (1 + rn2((int)mdef->m_lev+1));
  665.         if(vis)
  666.         pline("%s is %s!", Monnam(mdef),
  667.             (is_demon(mdef->data) || is_undead(mdef->data)) ?
  668.              "destroyed" : "killed");
  669.         else if(mdef->mtame)
  670.         You("have a sad feeling for a moment, then it passes.");
  671.         mondied(mdef);
  672.         ptr = grow_up(magr);
  673.         if(!ptr) return(-1);
  674.         return(2);
  675.     }
  676.     return(1);
  677. }
  678.  
  679. #endif /* OVLB */
  680. #ifdef OVL0
  681.  
  682. int
  683. noattacks(ptr)            /* returns 1 if monster doesn't attack */
  684.     struct    permonst *ptr;
  685. {
  686.     int i;
  687.  
  688.     for(i = 0; i < NATTK; i++)
  689.         if(ptr->mattk[i].aatyp) return(0);
  690.  
  691.     return(1);
  692. }
  693.  
  694. #endif /* OVL0 */
  695. #ifdef OVLB
  696.  
  697. static void
  698. mrustm(magr, mdef, obj)
  699. register struct monst *magr, *mdef;
  700. register struct obj *obj;
  701. {
  702.     if (!magr || !mdef || !obj) return; /* just in case */
  703.     if (mdef->data == &mons[PM_RUST_MONSTER] &&
  704.                 objects[obj->otyp].oc_material == METAL &&
  705.                 !obj->rustfree && obj->spe > -2) {
  706.         if(obj->blessed && rn2(3)) {
  707.             if (cansee(mdef->mx, mdef->my))
  708.             pline("%s's weapon is not affected.", Monnam(magr));
  709.         } else {
  710.             if (cansee(mdef->mx, mdef->my))
  711.             pline("%s's %s!", Monnam(magr),
  712.                         aobjnam(obj, "corrode"));
  713.             obj->spe--;
  714.         }
  715.     }
  716. }
  717.  
  718. static void
  719. mswingsm(magr, mdef, otemp)
  720. register struct monst *magr, *mdef;
  721. register struct obj *otemp;
  722. {
  723.     char buf[BUFSZ];
  724.     Strcpy(buf, mon_nam(mdef));
  725.     if (!flags.verbose || Blind || otemp->olet != WEAPON_SYM) return;
  726.     pline("%s %s %s %s at %s.", Monnam(magr),
  727.           ((otemp->otyp >= SPEAR &&
  728.             otemp->otyp <= LANCE) ||
  729.            (otemp->otyp >= PARTISAN &&
  730.             otemp->otyp <= SPETUM) ||
  731.            otemp->otyp == TRIDENT) ? "thrusts" : "swings",
  732.           is_female(magr) ? "her" :
  733.           is_human(magr->data) ? "his" : "its",
  734.           xname(otemp), buf);
  735. }
  736.  
  737. #endif /* OVLB */
  738.